package com.zeus.core.log.appender;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.IThrowableProxy;
import ch.qos.logback.classic.spi.ThrowableProxy;
import ch.qos.logback.core.AppenderBase;
import com.zeus.common.log.ZeusLoggerConfig;
import com.zeus.common.utils.StackTraceUtils;
import com.zeus.core.context.ZeusContext;
import com.zeus.core.report.ZeusReportClient;
import com.zeus.core.report.ZeusReportLogbackClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Logback日志监控
 *
 * @author wangfeixiong126@gmail.com  2021/4/28 14:08
 */
public class LogbackMonitorAppender extends AppenderBase<ILoggingEvent> {
    private final static Logger logger = LoggerFactory.getLogger(LogbackMonitorAppender.class);

    /**
     * 构造
     *
     * @author wangfeixiong126@gmail.com  2021/4/28 14:09
     */
    public LogbackMonitorAppender() {
        // default
    }

    /**
     * 自定义append
     *
     * @param iLoggingEvent iLoggingEvent
     * @author wangfeixiong126@gmail.com  2021/4/28 14:09
     */
    @Override
    protected void append(ILoggingEvent iLoggingEvent) {
        try {
            if (iLoggingEvent != null && iLoggingEvent.getLevel().isGreaterOrEqual(Level.ERROR)) {
                // 开关
                if (!ZeusContext.getContext().alarmEnable()) {
                    return;
                }
                // 内容是否可以忽略
                if (ZeusContext.getContext().checkAlarmContentIgnore(iLoggingEvent.getLoggerName(),
                    iLoggingEvent.getFormattedMessage(), getStackTrace(iLoggingEvent.getThrowableProxy()))) {
                    return;
                }

                // 发送报告
                ZeusReportClient client = new ZeusReportLogbackClient(iLoggingEvent);
                client.complete();
            }
        } catch (Throwable e) {
            if (logger.isWarnEnabled() && ZeusLoggerConfig.needEnableLogger()) {
                logger.warn("### Zeus日志监控模块, Logback日志监控服务执行失败 >> errMsg = {}", e.getMessage());
            }
        }
    }

    /**
     * 获取appender名称
     *
     * @return appender名称
     * @author wangfeixiong126@gmail.com  2021/6/3 16:19
     */
    @Override
    public String getName() {
        return getClass().getName();
    }

    /**
     * 获取堆栈信息
     * 
     * @param iThrowableProxy iThrowableProxy
     * @return 堆栈信息
     * @author f1ybear_wang  2022/2/8 6:36 下午
     */
    private String getStackTrace(IThrowableProxy iThrowableProxy) {
        try {
            if (iThrowableProxy == null) {
                return null;
            }
            if (iThrowableProxy instanceof ThrowableProxy) {
                ThrowableProxy throwableProxy = (ThrowableProxy)iThrowableProxy;
                Throwable ex = throwableProxy.getThrowable();
                if (ex != null) {
                    return StackTraceUtils.getStackTrace(ex);
                }
            }
        } catch (Throwable e) {
            if (logger.isWarnEnabled() && ZeusLoggerConfig.needEnableLogger()) {
                logger.warn("### Zeus日志监控模块, Logback日志监控服务加工堆栈信息出现异常:", e);
            }
        }
        return null;
    }
}
